import json
import os
import shutil
from urllib import parse

PROJECT_PATH = os.getcwd().split('common')[0]


def str_to_hex(s):
    tmp = ''
    for c in s:
        ss = '\\x%0.2X' % ord(c)
        tmp += ss
    return tmp


def find_static_path(path):
    for f in os.listdir(path):
        if os.path.isdir(path + f):
            if f == 'static':
                return path + f + os.path.sep
            else:
                p = find_static_path(path + f + os.path.sep)
                if p:
                    return p


def get_js_encrypted_path():
    static = find_static_path(PROJECT_PATH)
    p = static + 'encrypted_js'
    if not os.path.exists(p):
        os.mkdir(p)
    return p


def get_js_path():
    static = find_static_path(PROJECT_PATH)
    js_path = static + 'js'
    return js_path


def replace_js_str(s, d):
    if len(s) < 2:
        return s
    new_s = s
    for k in d.keys():
        s_list = new_s.split(k)
        if len(s_list) > 2:
            new_s = d[k].join(s_list)
            break
    return new_s


def __mix_js(file_path):
    new_file = file_path[:-3] + '__tmp.js'
    content = ''
    with open(file_path, 'rb') as file:
        i = 0
        while True:
            line = file.readline().decode(encoding='utf-8')
            line = line.strip(' ')
            if line.startswith('//'):
                line = ' '
            if not line:
                break
            line = line.split(' // ')[0]
            line = line.replace('\n', ' ').replace('\r', ' ').replace('  ', ' ').strip()

            if line:
                content += line

        sep = 'function'
        content = '====%s====' % content
        c = content.split(sep)
        c = [parse.quote(cc) for cc in c]

        # c: js 代码使用 sep 切分后的数组
        # s: sep, 即接切割符
        content = '''
            eval((function(c, s, f1, f3) {
                let ns = '';
                let cc = f1(c);
                for (let ss of cc) {
                    ss = f3(ss);
                    ns += ss + s;
                }
                ns = ns.substring(4, ns.length - s.length - 4);
                //console.log(ns);
                return ns;
            })('%s','%s', JSON.parse, decodeURIComponent));
        ''' % (json.dumps(c), sep)

        with open(new_file, 'wb') as new_f:
            new_f.write(content.encode('utf-8'))
        # print(content)
        os.remove(file_path)
        os.rename(new_file, file_path)


def __hex_js(file_path):
    new_file = file_path[:-3] + '__tmp.js'
    content = ''
    with open(file_path, 'rb') as file:
        while True:
            line = file.readline().decode(encoding='utf-8')
            line = line.strip(' ')
            if line.startswith('//'):
                line = ' '
            if not line:
                break
            line = line.split(' // ')[0]
            line = line.replace('\\', '\\\\')
            line = line.replace('"', '\\"')
            line = line.replace('\n', '').replace('\r', '').replace('  ', ' ').strip()

            if line:
                if not ('"' in line or "'" in line or '(/' in line or '\\x' in line):
                    line = str_to_hex(line)
                content += line
        content = 'eval("%s")' % content
        with open(new_file, 'wb') as new_f:
            new_f.write(content.encode('utf-8'))
        # print(content)
        os.remove(file_path)
        os.rename(new_file, file_path)


def encrypt_js():
    js_path = get_js_path()
    js_enc_path = get_js_encrypted_path()
    files = os.listdir(js_path)
    for f in files:
        if f[:1] == '.':
            continue
        js_new_file = js_enc_path + os.path.sep + f
        js_file = js_path + os.path.sep + f
        try:
            shutil.copy(js_file, js_new_file)
        except:
            pass
        __mix_js(js_new_file)
        __hex_js(js_new_file)


def recovery_js():
    js_path = get_js_path()
    js_en_path = get_js_encrypted_path()
    files = os.listdir(js_en_path)
    for f in files:
        js_file = js_path + os.path.sep + f
        old_js = js_en_path + os.path.sep + f
        try:
            shutil.copy(js_file, old_js)
        except:
            pass


encrypt_js()
